package com.hunan.api.catv.service.biz.ugc;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.hunan.api.catv.common.CacheName;
import com.hunan.api.catv.common.Constants;
import com.hunan.api.catv.common.ConstantsMsg;
import com.hunan.api.catv.entity.ServiceResult;
import com.hunan.api.catv.entity.po.Activity;
import com.hunan.api.catv.entity.po.UgcNews;
import com.hunan.api.catv.entity.vo.ActivityVo;
import com.hunan.api.catv.entity.vo.MemberVo;
import com.hunan.api.catv.entity.vo.SystemDictVo;
import com.hunan.api.catv.entity.vo.UgcNewsVo;
import com.hunan.api.catv.mq.MqConstants;
import com.hunan.api.catv.service.ResultService;
import com.hunan.api.catv.service.biz.comment.CommentBiz;
import com.hunan.api.catv.service.biz.member.MemberBiz;
import com.hunan.api.catv.service.biz.mq.MqBiz;
import com.hunan.api.catv.service.biz.system.SystemDictBiz;
import com.hunan.api.catv.service.impl.activity.ActivityService;
import com.hunan.api.catv.utils.GsonUtils;
import com.hunan.api.catv.utils.JacksonUtils;
import com.hunan.api.catv.utils.RedisUtils;
import org.apache.commons.compress.utils.Sets;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @Author: wangchao
 * @Date: 2020/9/22 20:16
 */
@CacheConfig(cacheNames = CacheName.ugcNews)
@Service
public class UgcNewsBiz extends ResultService {

    private static final String UGC_PRAISE_COUNT = "ugc_praise_";
    private static final String UGC_PRAISE_MEMBER_INFO = "ugc_member_";
    private static final String UGC_LIKE_YES = "1";
    private static final String UGC_LIKE_NO = "0";


    @Autowired
    private SystemDictBiz systemDictBiz;

    @Autowired
    private MemberBiz memberBiz;

    @Autowired
    private CommentBiz commentBiz;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private ActivityService activityService;

    @Autowired
    MqBiz mqBiz;

    /**
     * 允许查询的字典key
     */
    private final Set<String> allowKeySet = Sets.newHashSet("tourist_route_tag", "glod_eagle_tags");

    @Transactional(rollbackFor = Exception.class)
    public ServiceResult saveUgcNews(UgcNewsVo ugcNewsvo) {
        SystemDictVo dic = systemDictBiz.getByKey(Constants.app_init_conf);
        JsonArray array = GsonUtils.fromJson(dic.getDictValue(), JsonArray.class);
        array.forEach(a -> {
            JsonObject o = GsonUtils.fromJson(GsonUtils.toJson(a), JsonObject.class);
            String type = o.get("type").getAsString();
            Integer start = o.get("start").getAsInt();
            Integer end = o.get("end").getAsInt();
            Integer count = ThreadLocalRandom.current().nextInt(start, end + 1);
            if ("up".equals(type)) {
                ugcNewsvo.setBaseLike(count);
            }
            if ("play".equals(type)) {
                ugcNewsvo.setBasePlay(count);
            }
        });
        MemberVo memberVo = memberBiz.info(ugcNewsvo.getMemberId());
        ugcNewsvo.setMemberPhone(memberVo.getPhone());
        ugcNewsvo.setMemberName(memberVo.getNickName());
        if (!StringUtils.isEmpty(ugcNewsvo.getTags())) {
            ugcNewsvo.setTags(ugcNewsvo.getTags());
        }
        ugcNewsvo.setUgcId(IdUtil.simpleUUID());
        ugcNewsvo.setCTime(new Date());
        UgcNews ugcNews = new UgcNews();
        BeanUtils.copyProperties(ugcNewsvo, ugcNews);
        boolean insert = ugcNews.insert();
        if (insert) {
            redisUtils.delObjectCacheList(CacheName.ugcNews);
            return buildOK(true, ConstantsMsg.admin_add_success);
        }
        return buildFail(false, ConstantsMsg.admin_add_fail);
    }

    public PageInfo<UgcNewsVo> getUgcNewsList(Integer pageNum, Integer pageSize, String memberName, String memberPhone, String title, String state, String tag, String activityName) {
        List<Integer> activityIdList = new ArrayList<>();
        if (!StringUtils.isEmpty(activityName)) {
            Activity activity = new Activity();
            activity.setTitle(activityName);
            activityIdList = activityService.list(activity).stream().map(ActivityVo::getActivityId).filter(Objects::nonNull).collect(Collectors.toList());
        }
        List<UgcNews> ugcNewsList = new UgcNews().selectList(new QueryWrapper<UgcNews>()
                .like(!StringUtils.isEmpty(memberName), UgcNews.MEMBER_NAME, memberName)
                .like(!StringUtils.isEmpty(memberPhone), UgcNews.MEMBER_PHONE, memberPhone)
                .like(!StringUtils.isEmpty(title), UgcNews.TITLE, title)
                .like(!StringUtils.isEmpty(state), UgcNews.STATE, state)
                .like(!StringUtils.isEmpty(tag), UgcNews.TAGS, tag)
                .in(!StringUtils.isEmpty(activityName), UgcNews.ACTIVITY_ID, activityIdList)
                .orderByDesc(UgcNews.CTIME)
        );
        List<UgcNewsVo> list = new ArrayList<>();
        for (UgcNews ugcNews : ugcNewsList) {
            UgcNewsVo ugcNewsVo = getActivityName(ugcNews);
            list.add(ugcNewsVo);
        }
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(list);
    }

    private UgcNewsVo getActivityName(UgcNews ugcNews) {
        UgcNewsVo ugcNewsVo = new UgcNewsVo();
        BeanUtils.copyProperties(ugcNews, ugcNewsVo);
        ActivityVo activityVo = activityService.getById(ugcNews.getActivityId());
        ugcNewsVo.setActivityName(activityVo.getTitle());
        return ugcNewsVo;
    }

    public UgcNewsVo getUgcNewsInfo(String ugcNewsId) {
        UgcNews ugcNews = new UgcNews().selectById(ugcNewsId);
        return getActivityName(ugcNews);
    }

    @Transactional(rollbackFor = Exception.class)
    public ServiceResult updateUgcNews(UgcNewsVo ugcNewsvo) {
        UgcNews ugcNews = new UgcNews();
        BeanUtils.copyProperties(ugcNewsvo, ugcNews);
        boolean update = ugcNews.updateById();
        if (update) {
            redisUtils.delObjectCacheList(CacheName.ugcNews);
            return buildOK(true, ConstantsMsg.admin_add_success);
        }
        return buildFail(false, ConstantsMsg.admin_add_fail);
    }

    @Transactional(rollbackFor = Exception.class)
    public ServiceResult updateState(String ugcNewsId, Integer state) {
        UgcNews ugcNews = new UgcNews().selectById(ugcNewsId);
        ugcNews.setState(state);
        boolean updateState = ugcNews.updateById();
        if (updateState) {
            redisUtils.delObjectCacheList(CacheName.ugcNews);
            return buildOK(true, ConstantsMsg.admin_add_success);
        }
        return buildFail(false, ConstantsMsg.admin_add_fail);
    }

    @Cacheable(unless = "#result == null")
    public PageInfo<UgcNewsVo> ugcNewsList(Integer activityId, Integer pageNum, Integer pageSize, String state, String tag, Integer memberId) {
        PageHelper.startPage(pageNum, pageSize);
        List<UgcNews> ugcNewsList = new UgcNews().selectList(new QueryWrapper<UgcNews>()
                .like(!StringUtils.isEmpty(state), UgcNews.STATE, state)
                .like(!StringUtils.isEmpty(tag), UgcNews.TAGS, tag)
                .like(!StringUtils.isEmpty(activityId), UgcNews.ACTIVITY_ID, activityId)
                .orderByDesc(UgcNews.CTIME)
        );
        PageInfo<UgcNews> ugcNewsPageInfo = new PageInfo<>(ugcNewsList);
        ArrayList<UgcNewsVo> ugcNewsVoList = new ArrayList<>();
        ugcNewsList.forEach(ugcNews -> {
            ugcNews.setCTime(null); //LocalDateTime未格式化，不支持缓存
            UgcNewsVo tempVo = new UgcNewsVo();
            BeanUtils.copyProperties(ugcNews, tempVo);
            ugcNewsVoList.add(tempVo);
        });

        ugcNewsVoList.forEach(ugcNewsVo -> {
            MemberVo memberVo = memberBiz.info(ugcNewsVo.getMemberId());
            ugcNewsVo.setAvatarUrl(memberVo.getAvatarUrl());
            Map<String, Integer> map = commentBiz.countExcludeFail(ugcNewsVo.getUgcId(), Constants.UGC_ANSWER_TYPE);
            ugcNewsVo.setCommentCount(map.get("amount"));
            Object praiseCount = redisUtils.get(getPraiseCountKey(ugcNewsVo.getUgcId()));
            ugcNewsVo.setPraiseCount(praiseCount == null ? 0 : (Integer) praiseCount);
            String typeLog = (String) redisUtils.get(getMemberPraiseKey(ugcNewsVo.getUgcId(), memberId));
            ugcNewsVo.setPraiseState(StringUtils.isEmpty(typeLog) ? "0" : typeLog);

        });
        PageInfo<UgcNewsVo> pageInfo = new PageInfo<>();
        BeanUtils.copyProperties(ugcNewsPageInfo, pageInfo);
        pageInfo.setList(ugcNewsVoList);
        return pageInfo;
    }

    public String getTags(String tagKey) {
        if (allowKeySet.contains(tagKey)) {
            SystemDictVo systemDictVo = systemDictBiz.getByKey(tagKey);
            return systemDictVo == null ? "" : systemDictVo.getDictValue();
        }
        return "不在可查询范围";
    }

    public ServiceResult updatePraiseCount(String ugcId, Integer memberId, String type) {
        if (memberId == null) {
            return buildFail(ConstantsMsg.member_simpleInfo_fail);
        }
        UgcNews ugcNews = new UgcNews().selectById(ugcId);
        if (ugcNews == null) {
            return buildFail(ConstantsMsg.RESOURCE_DOES_NOT_EXIST_INOPERABLE);
        }
        String typeLog = (String) redisUtils.get(getMemberPraiseKey(ugcId, memberId));
        if (typeLog == null) {
            if (type.equals(UGC_LIKE_YES)) {
                redisUtils.incr(getPraiseCountKey(ugcId), 1);
                redisUtils.set(getMemberPraiseKey(ugcId, memberId), type);
            } else {
                return buildFail(ConstantsMsg.COMMENT_LIKE_UPDATE_EXCPITON);
            }
        } else {
            if (type.equals(UGC_LIKE_YES) && typeLog.equals(UGC_LIKE_NO)) {
                redisUtils.incr(getPraiseCountKey(ugcId), 1);
                redisUtils.set(getMemberPraiseKey(ugcId, memberId), type);
            } else if (type.equals(UGC_LIKE_NO) && typeLog.equals(UGC_LIKE_YES)) {
                redisUtils.decr(getPraiseCountKey(ugcId), 1);
                redisUtils.set(getMemberPraiseKey(ugcId, memberId), type);
            } else {
                return buildFail(ConstantsMsg.COMMENT_LIKE_UPDATE_EXCPITON);
            }
        }
        redisUtils.delObjectCacheList(CacheName.ugcNews);
        return buildOK("", "更新成功");
    }

    private String getMemberPraiseKey(String ugcId, Integer memberId) {
        return UGC_PRAISE_MEMBER_INFO + ugcId + "-" + memberId;
    }

    private String getPraiseCountKey(String ugcId) {
        return UGC_PRAISE_COUNT + ugcId;
    }

    /**
     * 保存用戶發佈視頻
     */
    public ServiceResult saveUserReleaseVideos(UgcNewsVo ugcNewsVo, Integer memberId) {
        MemberVo memberVo = memberBiz.info(memberId);
        ugcNewsVo.setMemberId(memberId);
        ugcNewsVo.setMemberPhone(memberVo.getPhone());
        ugcNewsVo.setMemberName(memberVo.getNickName());
        if (!StringUtils.isEmpty(ugcNewsVo.getTags())) {
            ugcNewsVo.setTags(ugcNewsVo.getTags());
        }
        ugcNewsVo.setUgcId(IdUtil.simpleUUID());
        ugcNewsVo.setCTime(new Date());
        //上传视频默认状态为6需腾讯云审核
        ugcNewsVo.setState(6);
        UgcNews ugcNews = new UgcNews();
        BeanUtils.copyProperties(ugcNewsVo, ugcNews);
        boolean insert = ugcNews.insert();
        if (insert) {
            redisUtils.delObjectCacheList(CacheName.ugcNews);
            redisUtils.hset(CacheName.releaseVideo, ugcNews.getUgcId(), JacksonUtils.toJsonObject(ugcNews), 1800L);
            //視頻審核
            mqBiz.push(MqConstants.UGC_RELEASE_VEDIO_EXCHANGE, MqConstants.UGC_RELEASE_VEDIO_ROUTINGKEY, JacksonUtils.toJsonString(ugcNews));
            return buildOK(true, ConstantsMsg.admin_add_success);
        }
        return buildFail(ConstantsMsg.admin_add_fail);
    }

    /**
     * 删除用户发布视频
     */
    public ServiceResult delUserReleaseVideos(String ugcId, Integer memberId) {
        UgcNews ugcNews = new UgcNews().selectOne(new QueryWrapper<UgcNews>().eq(UgcNews.UGC_ID, ugcId).eq(UgcNews.MEMBER_ID, memberId));
        if (ugcNews == null) {
            return buildFail("", ConstantsMsg.admin_select_fail);
        }
        boolean update = ugcNews.setDeleted(0).update(new QueryWrapper<UgcNews>().eq(UgcNews.UGC_ID, ugcId));
        if (update) {
            redisUtils.delObjectCacheList(CacheName.ugcNews);
            redisUtils.hdel(CacheName.releaseVideo, ugcId);
            return buildOK(true, ConstantsMsg.admin_del_success);
        }
        return buildFail(ConstantsMsg.admin_del_fail);
    }


    public PageInfo<UgcNews> getUserReleaseVideosByMemberId(int pageNum, int pageSize, Integer memberId) {
        PageHelper.startPage(pageNum, pageSize);
        List<UgcNews> ugcNewsList = new UgcNews().selectList(new QueryWrapper<UgcNews>()
                .eq(memberId != null, UgcNews.MEMBER_ID, memberId)
                //.eq(UgcNews.STATE, 1)
                .eq(UgcNews.DELETED, 1)
                .orderByDesc(UgcNews.CTIME)
        );
        return new PageInfo<>(ugcNewsList);
    }
}
